module lpuart_fifo#(
  parameter tx_data_width = 9,
  parameter tx_addr_width = $clog2(16), // 16 words
  parameter rx_data_width = 12,
  parameter rx_addr_width = $clog2(16)  // 16 words
)(
  input                      pclk,
  input                      presetn,
  input                      uart_clk,
  input                      uart_rst_n,

  input                      tx_push,
  input  [tx_data_width-1:0] tx_push_data,
  output                     tx_wempty,
  output                     tx_wfull,
  output                     tx_wone_eighth_thr,
  output                     tx_wone_quarter_thr,
  output                     tx_wone_half_thr,
  output                     tx_wthree_quarter_thr,
  output                     tx_wseven_eighth_thr,
  input                      tx_pop,
  output [tx_data_width-1:0] tx_pop_data,
  output                     tx_rempty,

  input                      rx_pop,
  output [rx_data_width-1:0] rx_pop_data,
  output                     rx_rempty,
  output                     rx_rfull,
  output                     rx_rone_eighth_thr,
  output                     rx_rone_quarter_thr,
  output                     rx_rone_half_thr,
  output                     rx_rthree_quarter_thr,
  output                     rx_rseven_eighth_thr,
  output                     rx_wfull,
  input                      rx_push,
  input  [rx_data_width-1:0] rx_push_data
);

// tx fifo
// wclk -> pclk
// rclk -> uart_clk
wire [tx_data_width-1:0] tx_rdata;
assign tx_pop_data = tx_rdata;
wire [tx_data_width-1:0] tx_wdata = tx_push_data;

lpuart_basic_async_fifo #(
  .DATA_WIDTH(tx_data_width),
  .ADDR_WIDTH(tx_addr_width)
) u0_tx_fifo
(
.wclk               (pclk),
.wrst_n             (presetn),
.winc               (tx_push),
.wdata              (tx_wdata),
.wempty             (tx_wempty),
.wfull              (tx_wfull),
.wone_eighth_thr    (tx_wone_eighth_thr),
.wone_quarter_thr   (tx_wone_quarter_thr),
.wone_half_thr      (tx_wone_half_thr),
.wthree_quarter_thr (tx_wthree_quarter_thr),
.wseven_eighth_thr  (tx_wseven_eighth_thr),

.rclk               (uart_clk),
.rrst_n             (uart_rst_n),
.rinc               (tx_pop),
.rdata              (tx_rdata),
.rempty             (tx_rempty),
.rfull              (),
.rone_eighth_thr    (),
.rone_quarter_thr   (),
.rone_half_thr      (),
.rthree_quarter_thr (),
.rseven_eighth_thr  ()
);

// rx fifo
// wclk -> uart_clk
// rclk -> pclk
wire [rx_data_width-1:0] rx_rdata;
assign rx_pop_data = rx_rdata;
wire [rx_data_width-1:0] rx_wdata = rx_push_data;

lpuart_basic_async_fifo #(
  .DATA_WIDTH(rx_data_width),
  .ADDR_WIDTH(rx_addr_width)
) u0_rx_fifo
(
.wclk                (uart_clk),
.wrst_n              (uart_rst_n),
.winc                (rx_push),
.wdata               (rx_wdata),
.wfull               (rx_wfull),
.wone_eighth_thr     (),
.wone_quarter_thr    (),
.wone_half_thr       (),
.wthree_quarter_thr  (),
.wseven_eighth_thr   (),

.rclk                (pclk),
.rrst_n              (presetn),
.rinc                (rx_pop),
.rdata               (rx_rdata),
.rempty              (rx_rempty),
.rfull               (rx_rfull),
.rone_eighth_thr     (rx_rone_eighth_thr),
.rone_quarter_thr    (rx_rone_quarter_thr),
.rone_half_thr       (rx_rone_half_thr),
.rthree_quarter_thr  (rx_rthree_quarter_thr),
.rseven_eighth_thr   (rx_rseven_eighth_thr)
);

endmodule
